package cn.feizhu.aimarket.ai.workflow.node;

import cn.feizhu.aimarket.ai.workflow.model.constant.WorkflowControlConstant;
import cn.feizhu.aimarket.ai.workflow.model.enums.NodeStatus;
import cn.feizhu.aimarket.model.dto.ai.outline.NovelOutlineResponse;
import cn.hutool.json.JSONUtil;
import com.alibaba.cloud.ai.graph.OverAllState;
import com.alibaba.cloud.ai.graph.action.NodeAction;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.ai.chat.client.ChatClient;

import java.util.Map;

/**
 * 人类反馈节点
 * 模拟人工审核大纲并提供反馈
 *
 * @author feizhu
 * @since 2025/10/16
 */

public class HumanFeedbackNode implements NodeAction {

    private static final Logger logger = LoggerFactory.getLogger(HumanFeedbackNode.class);

    // TODO 后期引入工厂创建和维护，Spring Ai示例是一个ChatClient的，这里改一下，感觉我们设计还是有问题
    // 引入ChatClient 由于不是Component不能通过@Resource注入，只能通过构造函数注入
//    @Resource
//    private ChatClient humanResultClient;

    private final ChatClient humanResultClient;
    private final Map<String, NodeStatus> node2Status;
    
    public static final String NODE_NAME = "human_feedback";

    /**
     * 通过构造函数注入
     */
    public HumanFeedbackNode(ChatClient humanResultClient, Map<String, NodeStatus> node2Status) {
        this.humanResultClient = humanResultClient;
        this.node2Status = node2Status;
    }

    @Override
    public Map<String, Object> apply(OverAllState state) {
        node2Status.put(NODE_NAME, NodeStatus.RUNNING);
        logger.info("=== 人类反馈节点开始执行 ===");
        try {
            // 获取生成的大纲 - 处理类型转换问题
            Object outlineObj = state.value(WorkflowControlConstant.OUTLINE).orElse(null);
            if (outlineObj == null) {
                throw new RuntimeException("未找到大纲数据");
            }

            NovelOutlineResponse outline;
            if (outlineObj instanceof NovelOutlineResponse) {
                // 如果已经是正确类型，直接使用
                outline = (NovelOutlineResponse) outlineObj;
            } else if (outlineObj instanceof Map) {
                // 如果是Map类型（LinkedHashMap），转换为JSON再解析为对象
                String jsonStr = JSONUtil.toJsonStr(outlineObj);
                outline = JSONUtil.toBean(jsonStr, NovelOutlineResponse.class);
                logger.info("已将LinkedHashMap转换为NovelOutlineResponse对象");
            } else {
                throw new RuntimeException("不支持的大纲数据类型: " + outlineObj.getClass().getName());
            }

            // 这里打印总览就行,
            logger.info("正在审核大纲: {}",  outline.getOverview());
            logger.info("章节总数: {}",  outline.getTotalChapters());
            outline.getChapters().forEach(chapter ->
                    logger.info("章节 {} 标题: {}, 全部内容: {}", chapter.getChapterNumber(), chapter.getTitle(), chapter.toString())
            );

            // 使用AI获取判断结果  TODO 这里是通过Spring AI Alibaba预置的human feedback获取的，Controller也是这个逻辑
            String feedback = (String) state.humanFeedback().data().get(WorkflowControlConstant.FEEDBACK);
            /** 反馈处理结果 - 数据类型: String (值: "APPROVED", "NEEDS_REVISION", "ERROR") */
            String feedbackResult = humanResultClient.prompt()
                    .user(feedback)
                    .call()
                    .chatResponse()
                    .getResult()
                    .getOutput()
                    .getText();

            // 返回反馈结果
            node2Status.put(NODE_NAME, NodeStatus.COMPLETED);
            return Map.of(
                    WorkflowControlConstant.FEEDBACK, feedback,
                    WorkflowControlConstant.FEEDBACK_RESULT, feedbackResult
            );

        } catch (Exception e) {
            logger.error("人类反馈节点执行异常", e);
            node2Status.put(NODE_NAME, NodeStatus.FAILED);
            return Map.of(
                    WorkflowControlConstant.FEEDBACK, "反馈处理失败：" + e.getMessage(),
                    WorkflowControlConstant.FEEDBACK_RESULT, "ERROR"
            );
        } finally {
            logger.info("=== 人类反馈节点执行完成 ===");
        }
    }

}
